package gsoc.ogsadai.model.diagram.providers;

import gsoc.ogsadai.model.diagram.edit.parts.ActivityTypeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.ActivityTypeInstanceNameEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.DataTypeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.InputStreamTypeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.InputStreamTypePipeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.InputTypeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.InputsTypeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.OutputStreamTypeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.OutputStreamTypePipeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.OutputsTypeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.ParallelType2EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.ParallelTypeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.ParallelTypeWorkflowCompartmentEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.PipelineType2EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.PipelineTypeActivityCompartment2EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.PipelineTypeActivityCompartment3EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.PipelineTypeActivityCompartmentEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.PipelineTypeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.SequenceType2EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.SequenceTypeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.WorkflowType2EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.WorkflowType3EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.WorkflowTypeEditPart;
import gsoc.ogsadai.model.diagram.edit.parts.WrappingLabel2EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.WrappingLabel3EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.WrappingLabel4EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.WrappingLabel5EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.WrappingLabel6EditPart;
import gsoc.ogsadai.model.diagram.edit.parts.WrappingLabelEditPart;
import gsoc.ogsadai.model.diagram.part.RequestVisualIDRegistry;
import gsoc.ogsadai.model.diagram.view.factories.ActivityTypeInstanceNameViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.ActivityTypeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.DataTypeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.InputStreamTypePipeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.InputStreamTypeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.InputTypeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.InputsTypeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.OutputStreamTypePipeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.OutputStreamTypeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.OutputsTypeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.ParallelType2ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.ParallelTypeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.ParallelTypeWorkflowCompartmentViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.PipelineType2ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.PipelineTypeActivityCompartment2ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.PipelineTypeActivityCompartment3ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.PipelineTypeActivityCompartmentViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.PipelineTypeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.SequenceType2ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.SequenceTypeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.WorkflowType2ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.WorkflowType3ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.WorkflowTypeViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.WrappingLabel2ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.WrappingLabel3ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.WrappingLabel4ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.WrappingLabel5ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.WrappingLabel6ViewFactory;
import gsoc.ogsadai.model.diagram.view.factories.WrappingLabelViewFactory;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.gmf.runtime.diagram.core.providers.AbstractViewProvider;
import org.eclipse.gmf.runtime.emf.type.core.IElementType;
import org.eclipse.gmf.runtime.emf.type.core.IHintedType;
import org.eclipse.gmf.runtime.notation.View;

/**
 * @generated
 */
public class RequestViewProvider extends AbstractViewProvider {

	/**
	 * @generated
	 */
	protected Class getDiagramViewClass(IAdaptable semanticAdapter,
			String diagramKind) {
		EObject semanticElement = getSemanticElement(semanticAdapter);
		if (WorkflowTypeEditPart.MODEL_ID.equals(diagramKind)
				&& RequestVisualIDRegistry.getDiagramVisualID(semanticElement) != -1) {
			return WorkflowTypeViewFactory.class;
		}
		return null;
	}

	/**
	 * @generated
	 */
	protected Class getNodeViewClass(IAdaptable semanticAdapter,
			View containerView, String semanticHint) {
		if (containerView == null) {
			return null;
		}
		IElementType elementType = getSemanticElementType(semanticAdapter);
		EObject domainElement = getSemanticElement(semanticAdapter);
		int visualID;
		if (semanticHint == null) {
			// Semantic hint is not specified. Can be a result of call from CanonicalEditPolicy.
			// In this situation there should be NO elementType, visualID will be determined
			// by VisualIDRegistry.getNodeVisualID() for domainElement.
			if (elementType != null || domainElement == null) {
				return null;
			}
			visualID = RequestVisualIDRegistry.getNodeVisualID(containerView,
					domainElement);
		} else {
			visualID = RequestVisualIDRegistry.getVisualID(semanticHint);
			if (elementType != null) {
				// Semantic hint is specified together with element type.
				// Both parameters should describe exactly the same diagram element.
				// In addition we check that visualID returned by VisualIDRegistry.getNodeVisualID() for
				// domainElement (if specified) is the same as in element type.
				if (!RequestElementTypes.isKnownElementType(elementType)
						|| (!(elementType instanceof IHintedType))) {
					return null; // foreign element type
				}
				String elementTypeHint = ((IHintedType) elementType)
						.getSemanticHint();
				if (!semanticHint.equals(elementTypeHint)) {
					return null; // if semantic hint is specified it should be the same as in element type
				}
				if (domainElement != null
						&& visualID != RequestVisualIDRegistry.getNodeVisualID(
								containerView, domainElement)) {
					return null; // visual id for node EClass should match visual id from element type
				}
			} else {
				// Element type is not specified. Domain element should be present (except pure design elements).
				// This method is called with EObjectAdapter as parameter from:
				//   - ViewService.createNode(View container, EObject eObject, String type, PreferencesHint preferencesHint) 
				//   - generated ViewFactory.decorateView() for parent element
				if (!WorkflowTypeEditPart.MODEL_ID
						.equals(RequestVisualIDRegistry
								.getModelID(containerView))) {
					return null; // foreign diagram
				}
				switch (visualID) {
				case PipelineTypeEditPart.VISUAL_ID:
				case ParallelTypeEditPart.VISUAL_ID:
				case ActivityTypeEditPart.VISUAL_ID:
				case InputsTypeEditPart.VISUAL_ID:
				case InputTypeEditPart.VISUAL_ID:
				case InputStreamTypeEditPart.VISUAL_ID:
				case DataTypeEditPart.VISUAL_ID:
				case OutputsTypeEditPart.VISUAL_ID:
				case OutputStreamTypeEditPart.VISUAL_ID:
				case SequenceType2EditPart.VISUAL_ID:
				case SequenceTypeEditPart.VISUAL_ID:
				case WorkflowType2EditPart.VISUAL_ID:
				case PipelineType2EditPart.VISUAL_ID:
				case ParallelType2EditPart.VISUAL_ID:
				case WorkflowType3EditPart.VISUAL_ID:
					if (domainElement == null
							|| visualID != RequestVisualIDRegistry
									.getNodeVisualID(containerView,
											domainElement)) {
						return null; // visual id in semantic hint should match visual id for domain element
					}
					break;
				case WrappingLabelEditPart.VISUAL_ID:
				case PipelineTypeActivityCompartmentEditPart.VISUAL_ID:
					if (PipelineTypeEditPart.VISUAL_ID != RequestVisualIDRegistry
							.getVisualID(containerView)
							|| containerView.getElement() != domainElement) {
						return null; // wrong container
					}
					break;
				case WrappingLabel3EditPart.VISUAL_ID:
				case PipelineTypeActivityCompartment2EditPart.VISUAL_ID:
					if (ParallelTypeEditPart.VISUAL_ID != RequestVisualIDRegistry
							.getVisualID(containerView)
							|| containerView.getElement() != domainElement) {
						return null; // wrong container
					}
					break;
				case WrappingLabel4EditPart.VISUAL_ID:
					if (SequenceTypeEditPart.VISUAL_ID != RequestVisualIDRegistry
							.getVisualID(containerView)
							|| containerView.getElement() != domainElement) {
						return null; // wrong container
					}
					break;
				case ActivityTypeInstanceNameEditPart.VISUAL_ID:
					if (ActivityTypeEditPart.VISUAL_ID != RequestVisualIDRegistry
							.getVisualID(containerView)
							|| containerView.getElement() != domainElement) {
						return null; // wrong container
					}
					break;
				case InputStreamTypePipeEditPart.VISUAL_ID:
					if (InputStreamTypeEditPart.VISUAL_ID != RequestVisualIDRegistry
							.getVisualID(containerView)
							|| containerView.getElement() != domainElement) {
						return null; // wrong container
					}
					break;
				case WrappingLabel2EditPart.VISUAL_ID:
				case PipelineTypeActivityCompartment3EditPart.VISUAL_ID:
					if (PipelineType2EditPart.VISUAL_ID != RequestVisualIDRegistry
							.getVisualID(containerView)
							|| containerView.getElement() != domainElement) {
						return null; // wrong container
					}
					break;
				case WrappingLabel5EditPart.VISUAL_ID:
				case ParallelTypeWorkflowCompartmentEditPart.VISUAL_ID:
					if (ParallelType2EditPart.VISUAL_ID != RequestVisualIDRegistry
							.getVisualID(containerView)
							|| containerView.getElement() != domainElement) {
						return null; // wrong container
					}
					break;
				case WrappingLabel6EditPart.VISUAL_ID:
					if (SequenceType2EditPart.VISUAL_ID != RequestVisualIDRegistry
							.getVisualID(containerView)
							|| containerView.getElement() != domainElement) {
						return null; // wrong container
					}
					break;
				default:
					return null;
				}
			}
		}
		return getNodeViewClass(containerView, visualID);
	}

	/**
	 * @generated
	 */
	protected Class getNodeViewClass(View containerView, int visualID) {
		if (containerView == null
				|| !RequestVisualIDRegistry.canCreateNode(containerView,
						visualID)) {
			return null;
		}
		switch (visualID) {
		case PipelineTypeEditPart.VISUAL_ID:
			return PipelineTypeViewFactory.class;
		case WrappingLabelEditPart.VISUAL_ID:
			return WrappingLabelViewFactory.class;
		case ParallelTypeEditPart.VISUAL_ID:
			return ParallelTypeViewFactory.class;
		case WrappingLabel3EditPart.VISUAL_ID:
			return WrappingLabel3ViewFactory.class;
		case SequenceTypeEditPart.VISUAL_ID:
			return SequenceTypeViewFactory.class;
		case WrappingLabel4EditPart.VISUAL_ID:
			return WrappingLabel4ViewFactory.class;
		case ActivityTypeEditPart.VISUAL_ID:
			return ActivityTypeViewFactory.class;
		case ActivityTypeInstanceNameEditPart.VISUAL_ID:
			return ActivityTypeInstanceNameViewFactory.class;
		case InputsTypeEditPart.VISUAL_ID:
			return InputsTypeViewFactory.class;
		case InputTypeEditPart.VISUAL_ID:
			return InputTypeViewFactory.class;
		case InputStreamTypeEditPart.VISUAL_ID:
			return InputStreamTypeViewFactory.class;
		case InputStreamTypePipeEditPart.VISUAL_ID:
			return InputStreamTypePipeViewFactory.class;
		case DataTypeEditPart.VISUAL_ID:
			return DataTypeViewFactory.class;
		case OutputsTypeEditPart.VISUAL_ID:
			return OutputsTypeViewFactory.class;
		case OutputStreamTypeEditPart.VISUAL_ID:
			return OutputStreamTypeViewFactory.class;
		case WorkflowType2EditPart.VISUAL_ID:
			return WorkflowType2ViewFactory.class;
		case PipelineType2EditPart.VISUAL_ID:
			return PipelineType2ViewFactory.class;
		case WrappingLabel2EditPart.VISUAL_ID:
			return WrappingLabel2ViewFactory.class;
		case ParallelType2EditPart.VISUAL_ID:
			return ParallelType2ViewFactory.class;
		case WrappingLabel5EditPart.VISUAL_ID:
			return WrappingLabel5ViewFactory.class;
		case SequenceType2EditPart.VISUAL_ID:
			return SequenceType2ViewFactory.class;
		case WrappingLabel6EditPart.VISUAL_ID:
			return WrappingLabel6ViewFactory.class;
		case WorkflowType3EditPart.VISUAL_ID:
			return WorkflowType3ViewFactory.class;
		case PipelineTypeActivityCompartmentEditPart.VISUAL_ID:
			return PipelineTypeActivityCompartmentViewFactory.class;
		case PipelineTypeActivityCompartment2EditPart.VISUAL_ID:
			return PipelineTypeActivityCompartment2ViewFactory.class;
		case PipelineTypeActivityCompartment3EditPart.VISUAL_ID:
			return PipelineTypeActivityCompartment3ViewFactory.class;
		case ParallelTypeWorkflowCompartmentEditPart.VISUAL_ID:
			return ParallelTypeWorkflowCompartmentViewFactory.class;
		}
		return null;
	}

	/**
	 * @generated
	 */
	protected Class getEdgeViewClass(IAdaptable semanticAdapter,
			View containerView, String semanticHint) {
		IElementType elementType = getSemanticElementType(semanticAdapter);
		if (!RequestElementTypes.isKnownElementType(elementType)
				|| (!(elementType instanceof IHintedType))) {
			return null; // foreign element type
		}
		String elementTypeHint = ((IHintedType) elementType).getSemanticHint();
		if (elementTypeHint == null) {
			return null; // our hint is visual id and must be specified
		}
		if (semanticHint != null && !semanticHint.equals(elementTypeHint)) {
			return null; // if semantic hint is specified it should be the same as in element type
		}
		int visualID = RequestVisualIDRegistry.getVisualID(elementTypeHint);
		EObject domainElement = getSemanticElement(semanticAdapter);
		if (domainElement != null
				&& visualID != RequestVisualIDRegistry
						.getLinkWithClassVisualID(domainElement)) {
			return null; // visual id for link EClass should match visual id from element type
		}
		return getEdgeViewClass(visualID);
	}

	/**
	 * @generated
	 */
	protected Class getEdgeViewClass(int visualID) {
		switch (visualID) {
		case OutputStreamTypePipeEditPart.VISUAL_ID:
			return OutputStreamTypePipeViewFactory.class;
		}
		return null;
	}

	/**
	 * @generated
	 */
	private IElementType getSemanticElementType(IAdaptable semanticAdapter) {
		if (semanticAdapter == null) {
			return null;
		}
		return (IElementType) semanticAdapter.getAdapter(IElementType.class);
	}
}
